import os, re, wx
from synthDriverHandler import VoiceInfo
from .msc import MscLogin
from .ibmeci import EciSynthesizer
import tones
selfDir = os.path.dirname(__file__)
mscLogin = None
def login():
    # msc登录
    global mscLogin
    mscLogin = MscLogin('1b24b601')
def logout():
    # msc退出
    global mscLogin
    del mscLogin
class Synthesizer:
    # 把讯飞合成器和 ibmeci 合成器整合起来
    def __init__(self):
        # 默认合成器是讯飞
        self.engine = 'msc'
        self.synths = {}
    def __del__(self):
        # 释放资源
        self.terminate()
    def getSynth(self, engine):
        # 获取一个合成器对象，按需创建
        if engine in self.synths.keys():
            return self.synths[engine]
        if engine == 'msc':
            self.synths[engine] = mscLogin.newSynthesizer()
        if engine == 'eci':
            self.synths[engine] = EciSynthesizer()
        else:return
        return self.synths[engine]
    def speak(self, text, callback, **params):
        # 朗读函数
        if not text:return
        def callbackSafe():
            if callback:
                wx.CallAfter(callback)
        if 'voice' in params.keys():
            voice = self.getVoice()
            self.setVoice(params['voice'])
            synth = self.getSynth(self.engine)
            self.setVoice(voice)
        else:
            synth = self.getSynth(self.engine)
        if not synth:return
        for k, v in list(params.items()):
            if not v:
                del params[k]
        # 过长的文本分段
        textiter = re.finditer(r'.{128}|.+', text, flags = re.S)
        def cb():
            try:
                match = next(textiter)
                synth.speak(match.group(), cb, **params)
            except StopIteration:
                if callback:
                    callbackSafe()
        cb()
    def pause(self, pause):
        # 暂停函数
        synth = self.getSynth(self.engine)
        if not synth:return
        synth.pause(pause)
    def stop(self):
        # 停止函数
        for synth in self.synths.values():
            synth.stop()
    def terminate(self):
        # 释放资源
        if not hasattr(self, 'synths'):return
        for synth in self.synths.values():
            synth.terminate()
        del self.synths
    def getVoices(self):
        # 获取所有的语音
        voices = []
        with open(os.path.join(selfDir, 'voices.txt'), 'r', encoding = 'utf-8') as f:
            for line in f.readlines():
                line = line.strip()
                if line.startswith('#'):continue
                columns = line.split('\t')
                info = VoiceInfo(columns[0], columns[1])
                info.engine = columns[2]
                voices.append((columns[0], info,))
        return voices
    def setVoice(self, name):
        # 设置语音
        for k, v in self.getVoices():
            if k == name:
                self.engine = v.engine
                break
        synth = self.getSynth(self.engine)
        if not synth:return
        synth.setVoice(name)
    def getVoice(self):
        # 获取语音
        synth = self.getSynth(self.engine)
        if not synth:return
        return synth.getVoice()
    def getTempos(self):
        # 获取所有播放倍速
        values = {
          0.3: '慢两倍',
          0.5: '慢一倍',
          1: '正常',
          2: '快两倍',
          3: '快三倍',
          4: '快四倍',
          5: '快五倍',
          6: '快六倍',
          7: '快七倍',
          8: '快八倍',
          9: '快九倍'
        }
        return [(k, VoiceInfo(k, v),) for k, v in values.items()]
    def getTempo(self):
        # 获取播放倍速
        synth = self.getSynth(self.engine)
        if not synth:return
        return synth.getTempo()
    def setTempo(self, value):
        # 设置播放倍速
        synth = self.getSynth(self.engine)
        if not synth:return
        synth.setTempo(value)
    def getSpeedIncreases(self):
        # 获取所有语速增强
        synth = self.getSynth(self.engine)
        if not synth:return
        return [(k, VoiceInfo(k, v),) for k, v in synth.getSpeedIncreases()]
    def setSpeedIncrease(self, value):
        # 设置语速增强
        synth = self.getSynth(self.engine)
        if not synth:return
        synth.setSpeedIncrease(value)
    def getSpeedIncrease(self):
        # 获取语速增强
        synth = self.getSynth(self.engine)
        if not synth:return
        return synth.getSpeedIncrease()
    def getRdns(self):
        # 获取所有数字读法
        synth = self.getSynth(self.engine)
        if not synth:return
        rdns = synth.getRdns()
        return [(k, VoiceInfo(k, v),) for k, v in rdns]
    def setRdn(self, rdn):
        # 设置数字读法
        synth = self.getSynth(self.engine)
        if not synth:return
        synth.setRdn(rdn)
    def getRdn(self):
        # 获取数字读法
        synth = self.getSynth(self.engine)
        if not synth:return
        return synth.getRdn()
    def getEffects(self):
        # 获取所有效果
        synth = self.getSynth(self.engine)
        if not synth:return
        effects = synth.getEffects()
        return [(k, VoiceInfo(k, v),) for k, v in effects]
    def setEffect(self, effect):
        # 设置效果
        synth = self.getSynth(self.engine)
        if not synth:return
        synth.setEffect(effect)
    def getEffect(self):
        # 获取效果
        synth = self.getSynth(self.engine)
        if not synth:return
        return synth.getEffect()
    def setSpeed(self, speed):
        # 设置语速
        synth = self.getSynth(self.engine)
        if not synth:return
        synth.setSpeed(speed)
    def getSpeed(self):
        # 获取语速
        synth = self.getSynth(self.engine)
        if not synth:return
        return int(synth.getSpeed())
    def setPitch(self, pitch):
        # 设置音高
        synth = self.getSynth(self.engine)
        if not synth:return
        synth.setPitch(pitch)
    def getPitch(self):
        # 获取音高
        synth = self.getSynth(self.engine)
        if not synth:return
        return int(synth.getPitch())
    def setVolume(self, volume):
        # 设置音量
        synth = self.getSynth(self.engine)
        if not synth:return
        synth.setVolume(volume)
    def getVolume(self):
        # 获取音量
        synth = self.getSynth(self.engine)
        if not synth:return
        return int(synth.getVolume())